import { ref, computed } from "vue";
import { defineStore } from "pinia";

const USER_KEY = "OA_USER_KEY";
const TOKEN_KEY = "OA_TOKEN_KEY";

export const PermissionChoices = {
  // 所有权限
  All: 0b111,
  // 普通员工权限
  Staff: 0b000,
  // 需要董事会权限
  Border: 0b001,
  // Team Leader权限
  Leader: 0b010,
};

export const useAuthStore = defineStore("auth", () => {
  let _user = ref({});
  let _token = ref("");

  function setUserToken(user, token) {
    // 保存到对象上（内存中）
    _user.value = user;
    _token.value = token;

    // 存储到浏览器的localStorage中（硬盘上)
    localStorage.setItem(USER_KEY, JSON.stringify(user));
    localStorage.setItem(TOKEN_KEY, token);
  }

  function clearUserToken() {
    // 清除内存中的数据
    _user.value = {};
    _token.value = "";

    // 清除localStorage中的数据
    localStorage.removeItem(USER_KEY);
    localStorage.removeItem(TOKEN_KEY);
  }

  // 计算属性
  let user = computed(() => {
    // 如果内存中没有数据，就从localStorage中读取
    // 在js中，空对象用if判断是true，空字符串用if判断是false
    if (Object.keys(_user.value).length === 0) {
      let user_str = localStorage.getItem(USER_KEY);
      if (user_str) {
        _user.value = JSON.parse(user_str);
      }
    }
    return _user.value;
  });

  let token = computed(() => {
    // 如果内存中没有数据，就从localStorage中读取
    if (!_token.value) {
      let token_str = localStorage.getItem(TOKEN_KEY);
      if (token_str) {
        _token.value = token_str;
      }
    }
    return _token.value;
  });

  let is_logined = computed(() => {
    // 使用user而不是_user，因为当页面重新加载时，_user会被重置为{}，而user是一个计算属性，它会从localStorage中读取数据
    // 貌似这个user计算属性外部调用和内部调用不太一样，外部调用时pinia会自动帮我们解包，所以不需要加.value
    // 但是内部调用时，pinia不会帮我们解包，所以需要加.value，因为计算属性也是一个ref对象
    if (Object.keys(user.value).length > 0 && token.value) {
      return true;
    }
    return false;
  });

  let own_permissions = computed(() => {
    let _permissions = PermissionChoices.Staff;
    if (is_logined.value) {
      // 判断是否为董事会成员
      if (user.value.department.name == "董事会") {
        _permissions |= PermissionChoices.Border;
      }
      if (user.value.department.leader == user.value.uid) {
        _permissions |= PermissionChoices.Leader;
      }
    }
    return _permissions;
  });

  function has_permission(permissions, opt = "|") {
    // opt可选值：
    // | 代表或运算
    // & 代表与运算
    let results = permissions.map(
      (permission) => (permission & own_permissions.value) == permission
    );
    if (opt == "|") {
      if (results.indexOf(true) != -1) {
        return true;
      } else {
        return false;
      }
    } else if (opt == "&") {
      if (results.indexOf(false) != -1) {
        return false;
      } else {
        return true;
      }
    }
  }

  return {
    setUserToken,
    user,
    token,
    is_logined,
    clearUserToken,
    has_permission,
  };
});
